#include "../../ExEngine/math/matrix.h"

#include "../../ExEngine/physics/actor.h"
#include "../../ExEngine/physics/physics.h"
#include "../../ExEngine/math/quaternion.h"
#include "../../ExEngine/common/util.h"
#include "../../ExEngine/engine/engine.h"
#include "../../ExEngine/engine/camera.h"
#include "../../ExEngine/render/d3d_mesh.h"
#include "../../ExEngine/render/d3d.h"
#include "../../ExEngine/sound/dsound.h"
#include "../../ExEngine/input/dinput.h"

#include "ent_slidedoor.h"
#include "player.h"
#include "../game/core.h"

/**********************************************************************
 *
 **********************************************************************/

CSlideDoor::CSlideDoor() : CObject()
{
	m_State = CSlideDoor::OPENING;
	m_isValid = true;
}

HRESULT CSlideDoor::Create()
{		
	CActor::ActorData data;
	data.initalTransform = m_transform;
	data.mass = 10.0f;
	data.friction = 0.0125f;
	data.restitution = 0.2f;
	data.maxForce = 200.0f;
	data.maxSlope = PI / 5.0f;

	if(FAILED(CEngine::GetInstance()->GetPhysics()->CreateActor("slide_door.HKX", &m_pPhysics, data, this)))
	{
		Release();
		return E_FAIL;
	}

	if(FAILED(CEngine::GetInstance()->GetRenderer()->CreateModel("slide_door.mdl", &m_pModel)))
	{
		Release();
		return E_FAIL;
	}
	//m_pPhysics->SetStill(true);
	//m_pPhysics->SetCollisionCallback(Game::g_Player);
	m_pModel->setRenderFlags(RENDER_DEFAULT);
	m_Anchor = m_transform.Translation();
	
	m_StateTimer.Set(2.5f);

	return S_OK;
}

HRESULT CSlideDoor::Release()
{	
	HRESULT result = S_OK;
	if(m_pModel)
	{
		m_pModel = NULL;
	}
	if(m_pPhysics)
	{
		CPhysics* pPhysics = CEngine::GetInstance()->GetPhysics();
		if(FAILED(pPhysics->ReleaseActor(m_pPhysics)))
			result = E_FAIL;
		m_pPhysics = NULL;
	}
	return result;
}

void CSlideDoor::Idle()
{
	
}

void CSlideDoor::setPosition(const Vector3f &position)
{
	m_transform = Matrix4f::identity();
	m_transform.SetTranslation(position); 
	if(m_pPhysics)
		m_pPhysics->SetTransform(m_transform);
	
}

void CSlideDoor::OnCollisionEvent(const Vector3f& contactPoint, const Vector3f& contactNormal, CObject* pOtherObject) {

}

bool CSlideDoor::isValid() {
	return m_isValid;
}

void CSlideDoor::Update(const float dt)
{

#define OPEN_DISPLACEMENT 3.0f
	switch(m_State) {

		case CSlideDoor::OPENING: 
			{
				m_pPhysics->SetLinearVelocity(m_transform.Left()*1.5);
				
				if(Vector3f::distance(&m_transform.Translation(), &m_Anchor) > OPEN_DISPLACEMENT) {
					m_transform.SetTranslation(m_transform.Translation() + m_transform.Left() * OPEN_DISPLACEMENT);
					m_StateTimer.Reset();
					m_StateTimer.Set(1.5f);
					m_StateTimer.Start();
					m_State = CSlideDoor::OPEN;
					m_pPhysics->SetLinearVelocity(Vector3f());
				}
			}break;
		case CSlideDoor::OPEN:
			{
				if(m_StateTimer.IsComplete()) {
					m_StateTimer.Reset();
					m_StateTimer.Set(2.5f);
					m_StateTimer.Start();
					m_State = CSlideDoor::SHUT;
					m_transform.SetTranslation(m_Anchor);
					m_pPhysics->SetTransform(m_transform);
				}
			}break;
		case CSlideDoor::SHUT: 
			{
				if(m_StateTimer.IsComplete())
					m_State = CSlideDoor::OPENING;
			}break;
	}

				m_transform = m_pPhysics->GetTransform();
	m_StateTimer.Update(dt);
	CEngine::PrintVector(m_transform.Translation(), "T");
	CEngine::PrintVector(m_Anchor, "A");
}

void CSlideDoor::Draw()
{	
	//GetRenderer()->DrawSphere(m_transform.Translation());
//	CEngine::PrintVector(m_transform.Translation(), "FB");
	if(m_pModel)
		m_pModel->Draw(m_transform,m_velocity);

}